package org.jma.app.ewisdom.services.utils;

import org.jma.app.ewisdom.entities.FileDescriptor;
import org.jma.app.ewisdom.entities.FilePart;
import org.jma.app.ewisdom.entities.FileLocator;

import java.io.*;
import java.util.ArrayList;


/**
 * Split a physical File in FilePart elements, updates the FileDescriptor and FilePart data
 * @author jesmari@ono.com
 * @version 1.0
 * @since 1.0
 */
public class FileSplitter extends Thread{

	private String pathFile;
    private String folderDest;
    private int nChunkSize;
    private FileDescriptor fileDescriptor;
    private String host;
    private int port;
    private String serverFolder;
 
    
    private final int BUFFER_SIZE = 1024;

    /**
     * FileSplitter constructor
     * @param pathFile
     * @param folderDest
     * @param nDim size of chunks in Kbytes
     * @param fileDescriptor
     * @param host
     * @param port
     * @param serverFolder
     */
    public FileSplitter (String  pathFile, 
    		String folderDest, 
    		int nDim, 
    		FileDescriptor fileDescriptor,
    		String host,
    		int port,
    		String serverFolder
    		)
	{
		this.pathFile = pathFile;
		this.folderDest = folderDest;
		this.nChunkSize = nDim;
        this.fileDescriptor = fileDescriptor;
        this.host=host;
        this.port=port;
        this.serverFolder=serverFolder;
    }

    public void run()
	{       
    	try {
        FileLocator fpl = new FileLocator();
        fpl.setHostName(this.host);
        fpl.setPort(port);
       
        File file = new File(this.pathFile);
        FileInputStream fileInputStream = new FileInputStream(file);
        byte[] buffer = new byte[BUFFER_SIZE];
        int bytesLeidos = 0;
        int i = 0;
        int parts = 0;
        
        File destinationFolder=new File(folderDest);
        if (!destinationFolder.exists()){
        	destinationFolder.mkdir();
        }
        
        FileOutputStream fw=new FileOutputStream(folderDest + fileDescriptor.getFileName() + "_" +fileDescriptor.getVer() + "." + 0 + ".part");
        FilePart part = new FilePart();
        part.setFilePartName( fileDescriptor.getFileName() + "_" +fileDescriptor.getVer()+ "." + 0 + ".part");
        fpl.setUrl("http://"+this.host+":"+this.port+this.serverFolder+part.getFilePartName());
        part.addLocator(fpl);
        ArrayList al=new ArrayList();
        
        while ((bytesLeidos = fileInputStream.read(buffer, 0, BUFFER_SIZE)) != -1) {
            if (i < nChunkSize) {
                fw.write(buffer, 0, bytesLeidos );
                i++;
            } else {
            	part.setFileDescriptor(fileDescriptor.hashCode()+"");
				part.setSize(i*1024);
                fw.close();
                al.add(part);
                parts++;
                fw=new FileOutputStream(folderDest + fileDescriptor.getFileName() + "_" +fileDescriptor.getVer() + "." + parts + ".part");
                fw.write(buffer, 0, bytesLeidos );
                i=0;                
                part = new FilePart();
                part.setFilePartName( fileDescriptor.getFileName() + "_" +fileDescriptor.getVer()+ "." + parts + ".part");
                fpl.setUrl("http://"+this.host+":"+this.port+this.serverFolder+part.getFilePartName());
                part.addLocator(fpl);
            }
        }
        if (i!=0){
        	part = new FilePart();
        	part.setFileDescriptor(fileDescriptor.hashCode()+"");
			part.setSize(bytesLeidos);
        	part.setFilePartName( fileDescriptor.getFileName() + "_" +fileDescriptor.getVer()+ "." + parts + ".part");
        	fpl.setUrl("http://"+this.host+":"+this.port+this.serverFolder+part.getFilePartName());
        	part.addLocator(fpl);
        	al.add(part);
        }
        
        fw.close();
        fileInputStream.close();
        
        FilePart[] fp=new FilePart[al.size()];
        for (int j=0;j<al.size();j++)
        	fp[j]=(FilePart)al.get(j);
      
        fileDescriptor.addNewVersion(fp);

   
    	}catch (IOException ioe){
    		ioe.printStackTrace();
    	}
	 }
}
